//
//  Medium.hpp
//  WiFiMACSim
//
//  Created by Christopher Kemsley on 3/31/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef WiFiMACSim_Medium_hpp
#define WiFiMACSim_Medium_hpp

#include <map>
#include <list>
#include <string>
#include <ostream>
#include "Types.hpp"
#include "Message.hpp"
#include "RunLoop.hpp"

SimNamespaceBegin


class	Medium : private RunLoopSource
{
public:
	
	static Medium&		shared () ;
	
	
	
	/** Basic Types **/
	
	typedef Message				Msg ;
	typedef std::list<Msg*>		MsgSet ;
	
	
	
	/** Creating mapped connections **/
	
	// "to" can receive connections from "from"
	void	buildConnection		( ID const & from , ID const & to ) ;
	void	destroyConnection	( ID const & from , ID const & to ) ;
	
	// They can each receive eachother's xmission
	void	buildConnectionPair		( ID const & from , ID const & to ) ;
	void	destroyConnectionPair	( ID const & from , ID const & to ) ;
	
	
	
	/** Processing transmissions **/
	
	void	registerMessage			( Msg * message ) ;
	
	// Returns all messages currently receivable by receiverID,
	// not just those sent TO receiverID. Messages with a remaining
	// duration of 0 have just completed xmission.
	MsgSet const	environment		( ID const & receiverID ) ;
	
	
	
	
private:
	IDSetMap	mRXReceiveSets ;	// mRXReceiveSets[rxID] = { ...txers... }
	MsgSet		mMessagesInFlight ;
	MsgSet		mEnqueuedMessages ;
	
	Medium () ;
	~Medium () ;
	
	virtual void	runFromRunLoop ( RunLoop & sender , RunLoop::Mode mode ) ;
} ;



std::ostream& operator<< ( std::ostream & str , Medium::MsgSet const & set ) ;




SimNamespaceEnd
#endif
